//
//  HOMIteratedVarWrapper.m
//  HigherOrderMessaging
//
//  Created by Ofri Wolfus on 18/10/05.
//  Copyright 2005 Ofri Wolfus. All rights reserved.
//

#import "HOMIteratedVarWrapper.h"
//#import "HOMRecycleBin.h"
#import "NSArrayHOMAdditions.h"
#import "NSObject-HOMPrivateAdditions.h"
#import "HOMUtilities.h"


@implementation HOMIteratedVarWrapper

//Create and init a new instance
+ (id)iteratedVarWrapperWithContents:(NSArray *)array autoReleases:(BOOL)flag {
	return [[self alloc] initWithContents:array autoReleases:flag];
}

//Designated initializer
- (id)initWithContents:(NSArray *)array autoReleases:(BOOL)flag {
	if (array) {
		contents = [[NSArray alloc] initWithArray:array];
		autoReleases = flag;
		nextIndex = 0;
		count = (contents ? [contents count] : 0);
		
		if (contents)
			objectAtIndexIMP = (IMPWithUnsignedArg)[contents methodForSelector:@selector(objectAtIndex:)];
		else
			objectAtIndexIMP = NULL;
	} else {
		self = nil;
	}
	
	return self;
}

//Make sure someone don't just alloc and init us
- (id)init {
	[self release];
	return nil;
}

//Clean up
- (void) dealloc {
	[contents release]; contents = nil;
	objectAtIndexIMP = NULL;	//Not really needed but anyway...
	
	[super dealloc];
}

//Return our autoReleases flag
- (BOOL)autoReleases {
	return autoReleases;
}

//Set our autoReleases flag
- (void)setAutoReleases:(BOOL)flag {
	autoReleases = flag;
}

//Get our contents. The message is prefixed so that any message will be forwarded to the real object (the
//original object may have its own -contents message).
- (NSArray *)HOMContents {
	return contents;
}

//Returns the reult of -nextObject of our enumerator
- (id)HOMNextObject {
	id result = nil;
	
	if (count > nextIndex && objectAtIndexIMP) {
		result = objectAtIndexIMP(contents, @selector(objectAtIndex:), nextIndex);
		++nextIndex;
	}
	
	if (!result && autoReleases)
		[self release];
	
	return result;
}

//We respond to anything as we're a simple wrapper arround some objects
- (BOOL)respondsToSelector:(SEL)aSelector {
	return YES;
}

//Pass back to our targate
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
	return [contents HOMMethodSignatureForSelector:aSelector];
}

//Forward any message back to our target or to its contents
- (void)forwardInvocation:(NSInvocation *)anInvocation {
	[contents makeObjectsPerformInvocation:anInvocation];
	
	if (autoReleases)
		[self release];
}

//Start iteration from the beginning
- (void)resetIteration {
	nextIndex = 0;
}

@end
